#include "StdAfx.h"
#include "DXDevice.h"
#include "GameEngine.h"
#include "Camera.h"
#include "DirectInput.h"

Camera::Camera(const D3DXVECTOR3& pos, const D3DXVECTOR3& target): m_EnableMov(true)
{
	D3DXMatrixIdentity(&m_View);
	D3DXMatrixIdentity(&m_Proj);
	m_Speed = 5;

	m_Fov = (float)D3DX_PI/4;
	m_Aspect = (float)GAME_ENGINE->GetWidth() / (float)GAME_ENGINE->GetHeight();
	m_NearPlane = 0.1f;
	m_FarPlane = 5000.0f;

	BuildProj();
		
	SetCamera(pos, target);

}

Camera::Camera()
{
	D3DXMatrixIdentity(&m_View);
	D3DXMatrixIdentity(&m_Proj);
	m_Speed = 5;

	m_Fov = (float)D3DX_PI/4;
	m_Aspect = (float)GAME_ENGINE->GetWidth() / (float)GAME_ENGINE->GetHeight();
	m_NearPlane = 0.1f;
	m_FarPlane = 1000.0f;

	BuildProj();

	SetCamera(D3DXVECTOR3(0, 10, -10), D3DXVECTOR3(0, 1, 0));
}

Camera::~Camera()
{

}

void Camera::SetCamera(const D3DXVECTOR3& pos, const D3DXVECTOR3& target)
{
	m_Pos = pos;
	D3DXVECTOR3 look, right;
	look = target - pos;
	m_Up = D3DXVECTOR3(0, 1, 0);
	D3DXVec3Normalize(&look, &look);
	m_LookAt = look + m_Pos;

	BuildView();
}

void Camera::SetLens(float fov, float aspect, float nearPlane, float farPlane)
{
	m_Fov = fov; m_Aspect = aspect; m_NearPlane = nearPlane; m_FarPlane = farPlane;
	BuildProj();
}

void Camera::SetSpeed(float speed) { 	m_Speed = speed; }
D3DXVECTOR3& Camera::GetPos() { return m_Pos; }
D3DXMATRIX& Camera::GetView() { return m_View; }
D3DXMATRIX& Camera::GetProj() { return m_Proj; }

void Camera::Tick( float dTime )
{
	// Keyboard Movement

	D3DXVECTOR3 dir(0,0,0), look, right;
	look = m_LookAt - m_Pos;
	D3DXVec3Normalize(&look, &look);
	D3DXVec3Cross(&right, &m_Up, &look);
	D3DXVec3Normalize(&right, &right);

	if(m_EnableMov)
	{
		if(DirectInput::GetSingleton()->KeyDown(DIK_W))
			dir += look;
		if(DirectInput::GetSingleton()->KeyDown(DIK_S))
			dir -= look;
		if(DirectInput::GetSingleton()->KeyDown(DIK_A))
			dir -= right;
		if(DirectInput::GetSingleton()->KeyDown(DIK_D))
			dir += right;

		D3DXVec3Normalize(&dir, &dir);

		if(DirectInput::GetSingleton()->KeyDown(DIK_LSHIFT))
			dir *= 5;

		dir *= m_Speed * dTime;
	}

	// Mouse Movement
	
	if(DirectInput::GetSingleton()->MouseButtonDown(0))
	{
		float pitch = DirectInput::GetSingleton()->GetMouseDY() / 200;
		float yaw = DirectInput::GetSingleton()->GetMouseDX() / 200;
		Rotate(pitch, yaw);
	}

	Move(dir);
}

void Camera::Move( const D3DXVECTOR3& tran )
{
	m_Pos += tran;
	m_LookAt += tran;
	BuildView();
}

void Camera::Rotate( float pitch, float yaw )
{
	D3DXVECTOR3 look, right;
	D3DXMATRIX matPitch, matYaw;

	D3DXVec3Normalize(&look, &(m_LookAt - m_Pos));
	D3DXVec3Cross(&right, &look, &m_Up);
	D3DXVec3Normalize(&right, &right);

	D3DXMatrixRotationAxis(&matPitch, &right, -pitch);
	D3DXMatrixRotationY(&matYaw, yaw);

	D3DXVec3TransformCoord(&look, &look, &(matPitch * matYaw));
	D3DXVec3TransformCoord(&m_Up, &m_Up, &(matPitch * matYaw));

	m_LookAt = look + m_Pos;
}

void Camera::BuildView()
{
	D3DXMatrixLookAtLH(&m_View, &m_Pos, &m_LookAt, &m_Up);
}

void Camera::BuildProj()
{
	D3DXMatrixPerspectiveFovLH(&m_Proj, m_Fov, m_Aspect, m_NearPlane, m_FarPlane);
}

void Camera::EnableCameraMovement( bool enable )
{
	m_EnableMov = enable;
}

void Camera::SetPos( const D3DXVECTOR3& pos )
{
	D3DXVECTOR3 mov = pos - m_Pos;
	Move(mov);
}

D3DXVECTOR3 Camera::GetLook()
{
	D3DXVECTOR3 look = m_LookAt - m_Pos;
	D3DXVec3Normalize(&look, &look);
	return look;
}

D3DXVECTOR3 Camera::GetRight()
{
	D3DXVECTOR3 right;
	D3DXVECTOR3 look = m_LookAt - m_Pos;
	D3DXVec3Normalize(&look, &look);
	D3DXVec3Cross(&right, &m_Up, &look);
	D3DXVec3Normalize(&right, &right);
	return right;
}